package com.polaris.live.ui.party.utils

import androidx.core.os.bundleOf
import androidx.lifecycle.LifecycleOwner
import com.polaris.live.adapter.party.SpectatorFragmentAdapter
import com.polaris.live.common.network.parseState
import com.polaris.live.common.util.LazyUtils
import com.polaris.live.constant.LiveConst
import com.polaris.live.resp.back_resp.DisplayUserBean
import com.polaris.live.ui.live.widget.PartyEditView
import com.polaris.live.ui.party.bean.PartySpectatorBean
import com.polaris.live.ui.party.bean.RoomState
import com.polaris.live.ui.party.fragment.PartySpectatorFragment
import com.polaris.live.ui.party.fragment.game.PartyGameSpectatorFragment
import com.polaris.live.ui.party.fragment.video.PartyVideoSpectatorFragment
import com.polaris.live.ui.party.listener.OnSpectatorFragmentListener
import com.polaris.live.utils.CommonUtils
import com.polaris.live.viewmodel.party.PartySpectatorModel

/**
 * 自动获取下个直播间
 * @author Created by 天晴 on 2024/2/28 14:21
 * @since 1.0.0
 **/
class AutoGetRoomProxy(
    @LiveConst.RequestType private val mRequestType: Int,   //请求类型
    private val mEditView: PartyEditView,
    private val mAdapter: SpectatorFragmentAdapter,
    private val mPartySpectatorModel: PartySpectatorModel,
    private val mOwner: LifecycleOwner,
    private val mOnSpectatorFragmentListener: OnSpectatorFragmentListener,
    private val addNextData: (dispaly: DisplayUserBean?) -> Unit,
) {

    init {
        mPartySpectatorModel.liveLoadMoreLiveData.observe(mOwner) { resultState ->
            parseState(resultState, {
                //如果获取是相同的，认为存在问题
                if (it.base.userId == mAnchorId) {
                    reFetchLoadMore()
                    addNextData.invoke(null)
                } else {
                    embedLiveMoreData(it)
                }
            }, {
                //出错重新获取新的
                reFetchLoadMore()
                addNextData.invoke(null)
            })
        }

    }

    private var mLiveMoreAttempt: Int = 1
    private var mAnchorId: Long? = null

    /**
     * 获取下一个直播间
     */
    fun getNextRoom(mAnchorId: Long) {
        this.mAnchorId = mAnchorId
        mPartySpectatorModel.getLoadMore(mRequestType, mAnchorId)
    }

    /**
     * 获取到数据
     */
    private fun embedLiveMoreData(liveData: DisplayUserBean) {
        if (liveData.base.liveType != null) { //直播类型不能为null
            mLiveMoreAttempt = 0
            mAdapter.addFragment(
                initPartySpectatorBean(
                    liveData.base.liveType,
                    liveData.base.userId,
                    mEditView,
                    liveData,
                    mOnSpectatorFragmentListener,
                    roomId = liveData.roomId
                )
            )
            addNextData.invoke(liveData)
        } else {
            reFetchLoadMore()
            addNextData.invoke(null)
        }

    }

    /**
     * 获取数据，并指数化延时
     */
    private fun reFetchLoadMore() {
        mAnchorId?.let {
            mPartySpectatorModel.getLoadMore(
                mRequestType,
                it,
                LazyUtils.exponentialBackoff(mLiveMoreAttempt++)
            )
        }

    }

    companion object {

        /**
         * 初始化一个数据
         */
        fun initPartySpectatorBean(
            @LiveConst.LiveType liveType: Int,
            userId: Long,
            editView: PartyEditView,
            liveData: DisplayUserBean?,
            listener: OnSpectatorFragmentListener,
            isMatchCome: Boolean? = null,
            soundStatus: Boolean? = null,
            roomId: String? = null,
        ): PartySpectatorBean {
            val instance = when (liveType) {
                LiveConst.Type.PARTY_LIVE -> PartySpectatorFragment()
                LiveConst.Type.VIDEO_PARTY -> PartyVideoSpectatorFragment()
                LiveConst.Type.PARTY_GAME_LIVE -> PartyGameSpectatorFragment()
                else -> throw Exception("No mLiveType")
            }
            return PartySpectatorBean(
                userId,
                liveType,
                instance.apply {
                    arguments = bundleOf(
                        "anchorId" to userId,
                        LiveConst.Params.IS_MATCH_COME_GAME to isMatchCome,
                        LiveConst.Params.SOUND_STATUS to soundStatus,
                        "fragmentPageId" to CommonUtils.uuid()
                    )
                    setOnSpectatorFragmentListener(listener)
                    setEditView(editView)
                },
                RoomState.PREPARE,
                0,
                liveData,
                null,
                roomId
            )
        }
    }

}